#ifndef __NET_PACKET_POOL_HPP__
#define __NET_PACKET_POOL_HPP__

#include "NetPacket.h"
#include <mutex>
#include <atomic>
#include "ThreadSafeQueue.hpp"

namespace LiteNetLib
{
    class NetPacketPool
    {
    private:
        ThreadSafeQueue<NetPacket *> m_poolPacketQueue;

    private:
        NetPacketPool();
        ~NetPacketPool();

    public:
        static NetPacketPool &GetInstance();

        /***********************************************************************************************************
         * @brief 获取一个已经写入了数据的 NetPacket， 其 rawData 的大小为 property 占用的包头长度 + length
         * @param property 数据包类型
         * @param data 要写入的数据，property 占用的头部数据之后的写入内容
         * @param length data 的数据长度
        ***********************************************************************************************************/
        NetPacket *getWithData(PacketProperty property, const char* data, uint32_t length);

        /***********************************************************************************************************
         * @brief 获取一个规定了数据区长度的 NetPacket，其rawData的大小为 property 占用的包头长度 + size
         * @param property 数据包类型
         * @param size 数据包大小，这个大小 没有 包含了数据包头的大小
        ***********************************************************************************************************/
        NetPacket *getWithProperty(PacketProperty property, uint32_t size);

        /***********************************************************************************************************
         * @brief 获取一个规定了类型的 NetPacket，其rawData大小是未知，但最小是 property 占用的包头长度
         * @param property 数据包类型
         * @param size 数据包大小，这个大小是包含了数据包头部的大小
        ***********************************************************************************************************/
        NetPacket *getWithProperty(PacketProperty property);

        /***********************************************************************************************************
         * @brief 获取一个规定了长度的 NetPacket
         * @param size 数据包大小，包括了包头内容的大小
        ***********************************************************************************************************/
        NetPacket *getPacket(uint32_t size);
        
        /***********************************************************************************************************
         * @brief 回收数据包
         * @param netPacket 要回收的数据包
         * @return false:数据包被delete，true:数据包被放入回收队列中
        ***********************************************************************************************************/
        bool recycleOrDelete(NetPacket *netPacket);
    };
    
}

#endif
